package com.common.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.github.pagehelper.Page;

public class RelationShipToObjectUtil {

	public static void main(String[] args) {
		List list = new ArrayList();

		Map map = new HashMap();
		map.put("clientNo", "12");
		map.put("clientName", "abc");
		map.put("wuliao", "w1");
		list.add(map);

		map = new HashMap();
		map.put("clientNo", "12");
		map.put("clientName", "abc");
		map.put("wuliao", "w2");
		list.add(map);

		map = new HashMap();
		map.put("clientNo", "13");
		map.put("clientName", "abcd");
		map.put("wuliao", "w3");
		list.add(map);

		map = new HashMap();
		map.put("clientNo", "13");
		map.put("clientName", "abc");
		map.put("wuliao", "w4");
		list.add(map);

		String[] repeatField = { "clientNo", "clientName" };
		List result = getObjectDataList(repeatField, "clientNo", null, false, list);
//		System.out.println(result);
	}
	
	/**
	 * 将关系型一对多，转换为对象型一对多
	 * 
	 * @param repeatFields
	 *            为一的列（重复的列）
	 * @param key
	 *            在repeatFields中选一个作为主键
	 * @param subListKey
	 *            子列表key
	 * @param isMap
	 *            当每个子列表只有一个值的时候，true表示依然用Map表示，false表示直接加到subListKey所表示的数组中
	 * @param list
	 * @return
	 */
	public static Page getObjectDataForPage(String[] repeatFields, String key, String subListKey, boolean isMap,
			Page page) {
		
		List resultList = RelationShipToObjectUtil.getObjectDataList(repeatFields, key, subListKey, isMap,page.getResult());
		page.getResult().removeAll(page.getResult());
		page.getResult().addAll(resultList);
		return page;
		
	}

	/**
	 * 将关系型一对多，转换为对象型一对多
	 * 
	 * @param repeatFields
	 *            为一的列（重复的列）
	 * @param key
	 *            在repeatFields中选一个作为主键
	 * @param subListKey
	 *            子列表key
	 * @param isMap
	 *            当每个子列表只有一个值的时候，true表示依然用Map表示，false表示直接加到subListKey所表示的数组中
	 * @param Map 将key的值作为新的键
	 * @return
	 */
	public static Map getObjectData(String[] repeatFields, String key, String subListKey, boolean isMap,
			List<Map<String, String>> list) {
		if (list == null || list.isEmpty() || repeatFields == null || repeatFields.length == 0) {
            return null;
        }
		subListKey = subListKey == null ? "list" : subListKey;
		// 对象型一对多
		Map ormResult = new HashMap();
		int size = list.size();
		// 遍历关系数据
		for (int i = 0; i < size; i++) {
			// 取得主键数据
			Map<String, String> record = list.get(i);
			String keyValue = record.get(key);
			// 指定重复的列，只保留一条
			Map oneMap = (Map) ormResult.get(keyValue);
			// 如果存在重复记录
			if (oneMap == null) {
				oneMap = new HashMap();
				ormResult.put(keyValue, oneMap);
			}
			// 将多的一端保留
			List subList = (List) oneMap.get(subListKey);
			if (subList == null) {
				subList = new ArrayList();
				oneMap.put(subListKey, subList);
			}
			// 不重复的数据
			Map subMap = new HashMap();
			Iterator it = record.entrySet().iterator();
			//一的一端处理为oneMap，将多的一端保存为subList，并保存到oneMap
			while (it.hasNext()) {
				Map.Entry entry = (Entry) it.next();
				//如果oneMap的元素个数与repeatFields的元素个数+1一致(oneMap中已有subList元素)
				//表示已经得到了所有值，不需要继续计算 
				if (oneMap.size() != repeatFields.length + 1){
					for (String field : repeatFields) {
						// 不为重复的列 且 指定重复的列存在
						if (entry.getKey().equals(field)) {
							oneMap.put(field, record.get(field));
						}
					}
				}
				//排除一对多中多的一端的key
				if (oneMap.containsKey(entry.getKey())) {
					continue;
				}
				// 其他数据字段
				subMap.put(entry.getKey(), entry.getValue());
			}
			if (isMap) {
				subList.add(subMap);
			} else {
				subList.add(subMap.values().toArray()[0]);
			}
		}
		return ormResult;
	}

	/**
	 * 将关系型一对多，转换为对象型一对多
	 * 
	 * @param repeatFields
	 *            为一的列（重复的列）
	 * @param key
	 *            在repeatFields中选一个作为主键
	 * @param subListKey
	 *            子列表key
	 * @param isMap
	 *            当每个子列表只有一个值的时候，true表示依然用Map表示，false表示直接加到subListKey所表示的数组中
	 * @param List 
	 * @return
	 */
	public static List getObjectDataList(String[] repeatFields, String key, String subListKey, boolean isMap,
			List<Map<String, String>> list) {
		Map ormResult = RelationShipToObjectUtil.getObjectData(repeatFields, key, subListKey, isMap, list);
		List objList = new ArrayList();
		objList.addAll(ormResult.values());
		ormResult = null;
		return objList;
	}

}
